package com.miao.teacher.models;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.util.Log;

public class AMRFile {
	private static final String TAG = "AMRFile";
	private byte[] data;
	private int[] frameHeaderPos;
	private int numFrames;
	private boolean isValid;

	private final class AMR475 {
		static final int SIZE = 13;
		static final byte HEADER = 0X04;
	}

	private final class AMR515 {
		static final int SIZE = 14;
		static final byte HEADER = 0X0C;
	}

	private final class AMR590 {
		static final int SIZE = 16;
		static final byte HEADER = 0X14;
	}

	private final class AMR670 {
		static final int SIZE = 18;
		static final byte HEADER = 0X1C;
	}

	private final class AMR740 {
		static final int SIZE = 20;
		static final byte HEADER = 0X24;
	}

	private final class AMR795 {
		static final int SIZE = 21;
		static final byte HEADER = 0X2C;
	}

	private final class AMR1020 {
		static final int SIZE = 27;
		static final byte HEADER = 0X34;
	}

	private final class AMR1220 {
		static final int SIZE = 32;
		static final byte HEADER = 0X3C;
	}

	//
	public static AMRFile create(File file) {
		AMRFile amrFile = new AMRFile(file);
		//if (amrFile.isValid)
			return amrFile;
		//return null;
	}

	public static AMRFile create(String file) {
		AMRFile amrFile = new AMRFile(new File(file));
		//if (amrFile.isValid)
			return amrFile;
		//return null;
	}

	private AMRFile(File file) {
		isValid = true;
		try {
			FileInputStream fis = new FileInputStream(file);
			data = new byte[fis.available() - 6];
			frameHeaderPos = new int[data.length / 13 + 1];
			byte[] header = new byte[6];
			int headPos = 0;
			while (headPos != header.length) {
				headPos += fis.read(header, headPos, header.length - headPos);
			}
			// fis.read(header);
			Log.i(TAG, "" + header);
			// if(!("#!AMR"+'0X0A').equals(header)){
			// Log.i(TAG,"BAD Header!");
			// isValid=false;
			// }
			int pos = 0;
			while (pos != data.length) {
				pos += fis.read(data, pos, data.length - pos);
			}
			fis.close();
			countFrames();
		} catch (FileNotFoundException e) {
			isValid = false;
			e.printStackTrace();
		} catch (IOException e) {
			isValid = false;
			e.printStackTrace();
		}
	}

	public byte[] getFrames(int start, int end) {
		if (start >= end || end > numFrames)
			return null;
		byte[] re = new byte[frameHeaderPos[end] - frameHeaderPos[start]];
		System.arraycopy(data, frameHeaderPos[start], re, 0, re.length);
		return re;

	}

	public byte[] getFrames() {
		return data;
	}

	public int getNumFrames() {
		return numFrames;
	}

	private void countFrames() {
		int pos = 0;
		numFrames = 0;
		while (pos < data.length) {
			switch (data[pos]) {
			case AMR475.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR475.SIZE;
				break;
			case AMR515.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR515.SIZE;
				break;
			case AMR590.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR590.SIZE;
				break;
			case AMR670.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR670.SIZE;
				break;
			case AMR740.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR740.SIZE;
				break;
			case AMR795.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR795.SIZE;
				break;
			case AMR1020.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR1020.SIZE;
				break;
			case AMR1220.HEADER:
				frameHeaderPos[numFrames] = pos;
				++numFrames;
				pos += AMR1220.SIZE;
				break;
			default:
				++pos;
				break;
			}
		}
		frameHeaderPos[numFrames] = data.length;
	}
}
